'    Copyright 2008 Jan Molnar <jan.molnar@abds.de>
'
'    This file is part of JCQ.

'    JCQ is free software: you can redistribute it and/or modify
'    it under the terms of the GNU General Public License as published by
'    the Free Software Foundation, either version 2 of the License, or
'    (at your option) any later version.

'    JCQ is distributed in the hope that it will be useful,
'    but WITHOUT ANY WARRANTY; without even the implied warranty of
'    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
'    GNU General Public License for more details.

'    You should have received a copy of the GNU General Public License
'    along with JCQ. If not, see <http://www.gnu.org/licenses/>.

Public Class TlvMetaRequestData
    Inherits Tlv

    Public Sub New()
        MyBase.New(&H1)
    End Sub

    Public Overrides Function CalculateDataSize() As Integer
        If _MetaRequest IsNot Nothing Then Return _MetaRequest.CalculateTotalSize
    End Function

    Private _MetaRequest As MetaRequest
    Public Property MetaRequest() As MetaRequest
        Get
            Return _MetaRequest
        End Get
        Set(ByVal value As MetaRequest)
            _MetaRequest = value
        End Set
    End Property

    Public Overrides Function Serialize() As System.Collections.Generic.List(Of Byte)
        Dim data As List(Of Byte) = MyBase.Serialize()
        data.AddRange(_MetaRequest.Serialize)
        Return data
    End Function

    Public Overrides Sub Deserialize(ByVal data As System.Collections.Generic.List(Of Byte))
        Throw New NotImplementedException
    End Sub
End Class

Public Class TlvMetaResponseData
    Inherits Tlv

    Public Sub New()
        MyBase.New(&H1)
    End Sub

    Public Overrides Function CalculateDataSize() As Integer
        Throw New NotImplementedException
    End Function

    Private _MetaResponse As MetaResponse
    Public Property MetaResponse() As MetaResponse
        Get
            Return _MetaResponse
        End Get
        Set(ByVal value As MetaResponse)
            _MetaResponse = value
        End Set
    End Property

    Public Overrides Function Serialize() As System.Collections.Generic.List(Of Byte)
        Throw New NotImplementedException
    End Function

    Public Overrides Sub Deserialize(ByVal data As System.Collections.Generic.List(Of Byte))
        MyBase.Deserialize(data)

        Dim index As Integer = Tlv.SizeFixPart

        Do While index < data.Count
            Dim desc As MetaResponseDescriptor = MetaResponseDescriptor.GetDescriptor(index, data)

            Select Case desc.ResponseType
                Case MetaResponseType.EndOfOfflineMessageResponse
                    Dim resp As EndOfOfflineMessagesResponse
                    resp = New EndOfOfflineMessagesResponse
                    resp.Deserialize(data.GetRange(index, desc.TotalSize))
                    MetaResponse = resp
                Case MetaResponseType.OfflineMessageResponse
                    Dim resp As OfflineMessageResponse
                    resp = New OfflineMessageResponse
                    resp.Deserialize(data.GetRange(index, desc.TotalSize))
                    MetaResponse = resp
                Case MetaResponseType.MetaInformationResponse
                    MetaResponse = DeserializeMetaResponse(desc, data.GetRange(index, desc.TotalSize))
            End Select

            index += desc.TotalSize
        Loop
    End Sub

    Private Function DeserializeMetaResponse(ByVal desc As MetaResponseDescriptor, ByVal data As List(Of Byte)) As MetaResponse
        Select Case desc.ResponseSubType
            Case MetaResponseSubType.ShortUserInformationReply
                Dim resp As New MetaShortUserInformationResponse
                resp.Deserialize(data)
                Return resp
            Case MetaResponseSubType.SearchUserFoundReply
                Dim resp As New MetaSearchByUinResponse
                resp.Deserialize(data)
                Return resp
            Case MetaResponseSubType.SearchLastUserFoundReply
                Dim resp As New MetaSearchByUinResponse
                resp.Deserialize(data)
                Return resp
            Case Else
                Return Nothing
        End Select
    End Function
End Class

Public Class MetaResponseDescriptor

    Private _TotalSize As Integer
    Public ReadOnly Property TotalSize() As Integer
        Get
            Return _TotalSize
        End Get
    End Property

    Private _ResponseType As MetaResponseType
    Public Property ResponseType() As MetaResponseType
        Get
            Return _ResponseType
        End Get
        Set(ByVal value As MetaResponseType)
            _ResponseType = value
        End Set
    End Property

    Private _ResponseSubType As MetaResponseSubType
    Public Property ResponseSubType() As MetaResponseSubType
        Get
            Return _ResponseSubType
        End Get
        Set(ByVal value As MetaResponseSubType)
            _ResponseSubType = value
        End Set
    End Property

    Public Shared Function GetDescriptor(ByVal offset As Integer, ByVal bytes As System.Collections.Generic.List(Of Byte)) As MetaResponseDescriptor
        Dim data As List(Of Byte) = bytes.GetRange(offset, bytes.Count - offset)
        Dim desc As MetaResponseDescriptor = New MetaResponseDescriptor
        desc.Deserialize(data)
        Return desc
    End Function

    Private Sub Deserialize(ByVal data As List(Of Byte))
        Dim index As Integer

        _TotalSize = 2 + ByteConverter.ToUInt16LE(data.GetRange(index, 2))
        index += 2

        index += 4

        _ResponseType = DirectCast(CInt(ByteConverter.ToUInt16LE(data.GetRange(index, 2))), MetaResponseType)
        index += 2

        If _ResponseType = MetaResponseType.MetaInformationResponse Then
            index += 2

            _ResponseSubType = DirectCast(CInt(ByteConverter.ToUInt16LE(data.GetRange(index, 2))), MetaResponseSubType)
        End If
    End Sub
End Class